
use core::marker::PhantomData;

use embedded_hal::digital::StatefulOutputPin;
pub struct LedCommomAnode;
pub struct LedCommomCathod;


#[allow(non_camel_case_types)]
pub struct LED<Pin, Com> {
    pin: Pin,
    _com: PhantomData<Com>,
}


macro_rules! led_ops {
    ($com: ident, $on: ident, $off: ident) => {
        impl<Pin> LED<Pin, $com> 
            where Pin: StatefulOutputPin,
        {
            #[inline]
            pub fn turn_on(&mut self) {
                self.pin.$on().unwrap();
            }

            #[inline]
            pub fn turn_off(&mut self) {
                self.pin.$off().unwrap();
            }

            #[inline]
            pub fn toggle(&mut self) {
                self.pin.toggle().unwrap();
            }
        }
    };
}


led_ops!(LedCommomAnode, set_low, set_high);
led_ops!(LedCommomCathod, set_high, set_low);


pub trait Pin2Led<Pin, Com> {
    fn to_led(self, _com: Com) -> LED<Pin, Com>;
}


use stm32f1xx_hal::gpio::{
    Pin, Output
};

use super::pin::Pin as AdapteV1_Pin;

impl<const P: char, const N: u8, Mode, Com> Pin2Led<AdapteV1_Pin<Pin<P, N, Output<Mode>>>, Com> for Pin<P, N, Output<Mode>> {
    fn to_led(self, _com: Com) -> LED<AdapteV1_Pin<Self>, Com> {
        LED {
            pin: AdapteV1_Pin(self),
            _com: PhantomData,
        }
    }
}